<template>
  <h1>shallowRef / shallowReactive / readonly 演示</h1>
  <div>
    <h2>shallowRef 演示</h2>
    <div>
      <p>姓名: {{ person.name }}</p>
      <p>年龄: {{ person.age }}</p>
      <button @click="changePersonName">修改姓名</button>
      <button @click="changePersonAge">修改年龄</button>
      <button @click="changePerson">修改人</button>
    </div>
    <h2>shallowReactive 演示</h2>
    <div>
      <p>车: {{ car }}</p>
      <button @click="changeBrand">修改品牌</button>
      <button @click="changeColor">修改颜色</button>
      <button @click="changeEngine">修改引擎</button>
    </div>
    <h3>readonly 演示</h3>
    <div>
      <p>count1 = {{ count1 }}, count2 = {{ count2 }}</p>
      <button @click="changeCount1">修改count1</button>
    </div>
    <h3>shallowReadonly</h3>
    <div>
      <p>student1: {{ student1 }}</p>
      <p>student2: {{ student2 }}</p>
      <button @click="changeStudent2Age">student2 age + 1</button>
    </div>
  </div>
</template>

<script setup lang="ts">
import {
  shallowRef,
  shallowReactive,
  ref,
  readonly,
  shallowReadonly,
} from "vue";

// 使用了 shallowRef 后，只有改变了 .value 才能有响应式
const person = shallowRef({
  name: "张三",
  age: 18,
});

function changePersonName() {
  // 实际上，person 的值已经加了，只是没有响应式，不会更新页面
  person.value.name += "~";
}
function changePersonAge() {
  person.value.age += 1;
}
function changePerson() {
  person.value = {
    name: person.value.name + "~",
    age: person.value.age + 1,
  };
}

const car = shallowReactive({
  brand: "比亚迪",
  parts: {
    color: "red",
    engine: "X1",
  },
});
// 一级字段修改会触发页面重新渲染
function changeBrand() {
  car.brand = "雅迪";
}
// 不会触发页面渲染，但是实际上已经改了，下次页面重新渲染时会使用新数据
function changeColor() {
  car.parts.color = "green";
}
function changeEngine() {
  car.parts.engine = "X2";
}

const count1 = ref(1);
const count2 = readonly(count1);

function changeCount1() {
  count1.value += 1;
}
const student1 = ref({
  name: "xxx",
  age: 1,
});
const student2 = shallowReadonly(student1);
function changeStudent2Age() {
  // 不允许改变 value，但因为是 shallowReadonly，因此 value 里面的值可以改变
  // student2.value = {name: 'a', age: 2}; // 该代码不允许
  student2.value.age += 1;
}
</script>

<style scoped>
button {
  margin-right: 1em;
}
</style>
